#pragma once
#include<memory>
#include<unordered_map>
#include"net.hpp"

// 调度程序
class BaseCall
{
public:
    using ptr = std::shared_ptr<BaseCall>;
    BaseCall() {}
    virtual ~BaseCall() {}

    virtual void start(BaseConnection::ptr, BaseMessage::ptr, BaseProtocol::ptr) = 0;
};

template<typename T>
class CallBack : public BaseCall
{
public:
    using ptr = std::shared_ptr<CallBack<T>>;
    using caller = std::function<void(BaseConnection::ptr, std::shared_ptr<T>, BaseProtocol::ptr)>;
    CallBack(caller cb) : _call(cb) {}
    virtual ~CallBack() {}

    virtual void start(BaseConnection::ptr conn, BaseMessage::ptr msg, BaseProtocol::ptr protocol)
    {
        _call(conn, std::dynamic_pointer_cast<T>(msg), protocol);
    }
private:
    caller _call;
};

class Dispatcher
{
public:
    using ptr = std::shared_ptr<Dispatcher>;
    Dispatcher() {}
    ~Dispatcher() {}

    // 为每个消息类型设置单独的回调处理逻辑
    template<class T>
    void setCallBack(MSG_Type mtype, typename CallBack<T>::caller call)
    {
        typename CallBack<T>::ptr cb = std::make_shared<CallBack<T>>(call);
        _manager.insert({mtype, cb});
        LOG_INFO << "设置 MSG_Type = " << (int)mtype << "消息回调成功！";
    }

    // 设置到 MessageCallback()
    void onMessage(BaseConnection::ptr conn, BaseMessage::ptr msg, BaseProtocol::ptr protocol)
    {
        // 消息类型 ----- 回调方法
        auto it = _manager.find(msg->getType());
        if (it != _manager.end())
        {
            it->second->start(conn, msg, protocol);
        }
        else{
            LOG_WARN << "暂未设置对应的消息回调";
        }
    }

private:
    std::unordered_map<MSG_Type, BaseCall::ptr> _manager;
};

class DispatcherFactory
{
public:
    static Dispatcher::ptr create()
    {
        return std::make_shared<Dispatcher>();
    }
};